package com.lt.integration.jpa.component;


import com.lt.integration.jpa.component.common.Direction;
import com.lt.integration.jpa.component.hibernate.Updater;
import com.lt.integration.jpa.page.Pagination;

import javax.persistence.metamodel.Attribute;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 基础查询接口
 * @author xiaobin
 *
 * @param <T>
 * @param <QO>
 */
public interface BaseService<T extends BaseModel, QO extends BaseQO> {

	/**
	 * 根据ID获取实体
	 *
	 * @param id 查询的id
	 * @return 实体
	 */
	T get(Long id);

	/**
	 *
	 * @param id 查询的id
	 * @return 实体
	 */
	Optional<T> getById(Long id);

	/**
	 * 查询唯一对象
	 * 
	 * @param qo 查询对象
	 * @return 查询实体
	 */
	T queryUnique(QO qo);
	
	/**
	 * 查询唯一对象 可查询关联对象
	 * 
	 * @param qo 查询对象
	 * @return 查询实体
	 */
	T fetchUnique(QO qo);

	/**
	 * 查询所有记录 默认根据id asc排序
	 * @return 返回所有记录
	 */
	List<T> queryAll();

	/**
	 * 查询所有记录 id desc排序
	 * @return 返回所有记录
	 */
	List<T> queryAllOrderByIdDesc();

	/**
	 * 查询对象列表
	 * 
	 * @param qo 查询对象
	 * @return 查询实体列表
	 */
	List<T> queryList(QO qo);

	/**
	 * 查询实体列表
	 * 
	 * @param qo 查询对象
	 * @param maxSize		最大获取数量
	 * @return 查询实体列表
	 */
	List<T> queryList(QO qo, Integer maxSize);
	
	/**
	 * 查询实体列表
	 * 
	 * @param qo 查询对象
	 * @param offset		偏移量
	 * @param maxSize		最大获取数量
	 * @return 列表
	 */
	List<T> queryList(QO qo, Integer offset, Integer maxSize);
	
	/**
	 * 查询数量
	 * 
	 * @param qo 查询对象
	 * @return 查询数量
	 */
	Long queryCount(QO qo);

	/**
	 * 查询数量
	 *
	 * @param qo 查询对象
	 * @return 查询数量
	 */
	Long count(QO qo);
	
	/**
	 * 分页查询对象
	 * 
	 * @param qo 查询对象
	 * @return 查询实体分页列表
	 */
	Pagination<T> queryPagination(QO qo);

	/**
	 * 分页查询对象
	 *
	 * @param pagination
	 * @return 查询实体分页列表
	 */
	Pagination<T> queryPagination(Pagination<T> pagination);

    /**
     * 根据id的升序或者降序排序 
     * @param id 大于或小于此id的数据
     * @param qo 每页的数量 默认为10
     * @return 查询实体分页列表
     */
	Pagination<T> queryPagination(Long id, QO qo);
    
    /**
     * 根据id的升序或者降序排序 
     * @param id 大于或小于此id的数据
     * @param direction 排序 升序或者降序 默认为 {@link Direction#ASC}
     * @return 查询实体分页列表
     */
	Pagination<T> queryPagination(Long id, QO qo, Direction direction);
    
	/**
	 * 通过updater更新 可以通过updater指定需要更新的字段
	 * @param updater
	 * @return 更新的记录数
	 */
	int update(Updater updater);

	/**
	 *
	 * @param id 更新的记录的id
	 * @param attribute 更新的字段
	 * @param value 更新的记录的值
	 * @return 更新的记录数
	 */
	int update(Long id, Attribute<?, ?> attribute, Object value);

	/**
	 *
	 * @param id 更新的记录的id
	 * @param params 更新的字段和值
	 * @return 更新的记录数
	 */
	int update(Long id, Map<Attribute<?, ?>, Object> params);

	/**
	 * 保存
	 * @param entity 更新实体
	 * @return
	 */
	T update(T entity);
	
	/**
	 * 保存
	 * @param entity 保存实体
	 * @return
	 */
	T save(T entity);

	/**
	 * 直接保存
	 * @param entity 保存实体
	 * @return
	 */
	T persist(T entity);

	/**
	 * 批量保存实体
	 * @param entities 保存的实体
	 */
	void saveArray(T... entities);
	
	/**
	 * 批量保存实体
	 * 
	 * @param entities 保存的实体
	 */
	void saveList(List<T> entities);

	/**
	 * Flushes all pending changes to the database.
	 */
	void flush();

	/**
	 * Saves an entity and flushes changes instantly.
	 *
	 * @param entity
	 * @return the saved entity
	 */
	T saveAndFlush(T entity);

	/**
	 * 批量更新实体
	 * 
	 * @param entities 更新的实体
	 */
	void updateArray(T... entities);
	
	/**
	 * 批量更新实体
	 * 
	 * @param entities 更新的实体
	 */
	void updateList(List<T> entities);

	/**
	 * 批量删除
	 * @param entities 要删除的实体
	 */
	void batchDelete(List<T> entities);

	/**
	 * 根据ID删除实体（物理删除）
	 *
	 * @param id 实体主键
	 */
	void deleteById(Long id);
	
	/**
	 * 根据ID数组批量删除实体
	 * @param ids 实体主键
	 */
	void deleteByIds(Long... ids);
	

}
